package petrieditor.visual.util;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public class GradientPanel extends JPanel {
    protected BufferedImage gradientImage;
    protected Color gradientStart = new Color(195, 217, 255);
    protected Color gradientEnd = new Color(232, 238, 247);

    public GradientPanel() {
        this(new BorderLayout());
    }

    public GradientPanel(LayoutManager layout) {
        super(layout);
        addComponentListener(new GradientCacheManager());
    }

    protected void paintComponent(Graphics g) {
        createImageCache();

        if (gradientImage != null) {
            Shape clip = g.getClip();
            Rectangle bounds = clip.getBounds();
            Image backgroundImage = gradientImage.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
            g.drawImage(backgroundImage, bounds.x, bounds.y, null);
        }
    }

    protected void createImageCache() {
        int width = getWidth();
        int height = getHeight();

        if (width == 0 || height == 0) {
            return;
        }

        if (gradientImage == null ||
                width != gradientImage.getWidth() ||
                height != gradientImage.getHeight()) {

            gradientImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            Graphics2D g2 = gradientImage.createGraphics();
            GradientPaint painter = new GradientPaint(0, 0, gradientEnd, 0, height, gradientStart);
            g2.setPaint(painter);
            Rectangle2D rect = new Rectangle2D.Double(0, 0, width, height);
            g2.fill(rect);

//            painter = new GradientPaint(0, height / 2, gradientStart,
//                    0, height, gradientEnd);
//            g2.setPaint(painter);
//            rect = new Rectangle2D.Double(0, (height / 2.0) - 1.0, width, height);
//            g2.fill(rect);

            g2.dispose();
        }
    }

    private void disposeImageCache() {
        synchronized (gradientImage) {
            gradientImage.flush();
            gradientImage = null;
        }
    }

    private class GradientCacheManager implements ComponentListener {
        public void componentResized(ComponentEvent e) {
        }

        public void componentMoved(ComponentEvent e) {
        }

        public void componentShown(ComponentEvent e) {
        }

        public void componentHidden(ComponentEvent e) {
            disposeImageCache();
        }

    }
}
